package cn.edu.cqut.mdm.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.sf.json.JSONArray;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.edu.cqut.mdm.container.InvokableModuleContainer;
import cn.edu.cqut.mdm.container.LocalDefinedModuleContainer;
import cn.edu.cqut.mdm.container.PublisherDispatcherContainer;
import cn.edu.cqut.mdm.core.GlobalConfigManager;
import cn.edu.cqut.mdm.core.module.ModuleEntity;
import cn.edu.cqut.mdm.core.module.PublishStatus;
import cn.edu.cqut.mdm.core.module.PublishStatus.Status;
import cn.edu.cqut.mdm.core.module.RemoteModuleEntity;
import cn.edu.cqut.mdm.core.publisherdispatcher.PublisherDispatcher;
import cn.edu.cqut.mdm.initialize.ModuleFinder;
import cn.edu.cqut.mdm.web.bean.ModuleEntityBean;
import cn.edu.cqut.mdm.web.bean.RemoteModuleEntityBean;

@Controller
@RequestMapping("/admin")
public class AdminController {
	
	@RequestMapping("/index")
	public String index() {
		return "login";
	}
	@RequestMapping("/login")
	public String login(String username, String password, Model model) {
		String users = GlobalConfigManager.getInstance().get(GlobalConfigManager.USERS);
		String[] userpasses = users.split(",");
		for(String userpass : userpasses) {
			String[] userandpass = userpass.split(";");
			if(username.equals(userandpass[0]) && password.equals(userandpass[1])) {
				return "redirect:publishManage.do";
			}
		}
		model.addAttribute("error", true);
		return "login";
	}
	
	@RequestMapping("/publishManage")
	public String publishManage(Model model) {
		Collection<PublisherDispatcher> publisherDispatchers = PublisherDispatcherContainer.getInstance().getAllPublisherDispatcherMap().values();
		Collection<ModuleEntity> moduleEntities = LocalDefinedModuleContainer.getInstance().getAllModuleMap().values();
		List<ModuleEntityBean> beans = new ArrayList<ModuleEntityBean>();
		for(ModuleEntity moduleEntity : moduleEntities) {
			ModuleEntityBean bean = ModuleEntityBean.fromModuleEntity(moduleEntity);
			for(PublisherDispatcher publisherDispatcher : publisherDispatchers) {
				PublishStatus publishStatus = moduleEntity.getPublishStatus(publisherDispatcher.getName());
				if(publishStatus == null) {
					bean.addPublishStatus(new PublishStatus(publisherDispatcher, moduleEntity));
				} else {
					bean.addPublishStatus(publishStatus);
				}
			}
			beans.add(bean);
		}
		model.addAttribute("modules", beans);
		model.addAttribute("publisherDispatchers", publisherDispatchers);
		return "publish-manage";
	}
	@RequestMapping("/changeStatus")
	@ResponseBody
	public String changeStatus(String moduleId, String publisherName, String nextStatus) {
		if(nextStatus.equals(Status.PUBLISHED.toString())) {
			ModuleEntity moduleEntity = LocalDefinedModuleContainer.getInstance().getModule(moduleId);
			PublisherDispatcherContainer.getInstance().getPublisherDispatcher(publisherName).getPublisher().publish(moduleEntity);
		} else {
			PublisherDispatcherContainer.getInstance().getPublisherDispatcher(publisherName).getPublisher().unpublish(moduleId);
		}
		return "success";
	}
	
	@RequestMapping("/lookupManage")
	public String lookupManage(Model model) {
		Collection<List<RemoteModuleEntity>> col = InvokableModuleContainer.getInstance().getAllModuleMap().values();
		List<RemoteModuleEntityBean> beans = new ArrayList<RemoteModuleEntityBean>();
		for(List<RemoteModuleEntity> remoteModuleEntities : col) {
			beans.add(new RemoteModuleEntityBean(remoteModuleEntities.get(0).getUid(), remoteModuleEntities.get(0).getName(), remoteModuleEntities));
		}
		model.addAttribute("beans",  beans);
		return "lookup-manage";
	}
	
	@RequestMapping(value = "/{moduleId}/resort")
	@ResponseBody
	public String resort(@PathVariable("moduleId")String moduleId, String json) {
		List<Integer> ids = JSONArray.toList(JSONArray.fromObject(json), Integer.class);
		List<RemoteModuleEntity> moduleEntitys = InvokableModuleContainer.getInstance().getModule(moduleId);
		List<RemoteModuleEntity> newList = new ArrayList<RemoteModuleEntity>();
		for(int i = 0;i < ids.size();i++) {
			for(int j = 0;j < moduleEntitys.size();j++) {
				if(moduleEntitys.get(j).getRandomId() == ids.get(i)) {
					newList.add(moduleEntitys.get(j));
					break;
				}
			}
		}
		InvokableModuleContainer.getInstance().putModule(moduleId, newList);
		return "success";
	}
	
	@RequestMapping(value = "/refind")
	public String refind() {
		new ModuleFinder().findModules();
		return "redirect:lookupManage.do";
	}
}